package luke.media.video;


import luke.core.logging.LogUtil;
import luke.system.callback.ProgressCallback;

import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;

import java.util.List;

/**
 * 视频合并和音频叠加处理器
 * 合并视频和叠加视频应该另外一个类，不应该放在视频渲染器里面
 *
 * ==================== 重要说明 ====================
 * 此类职责已调整，仅负责：
 * 1. 合并多个视频片段并添加音频轨道
 * 2. 不再包含任何并行处理逻辑
 * 3. 不再包含频谱分析或视频生成逻辑
 * =================================================
 */
public class SegmentedVideoProcessor {
    
    /**
     * 合并视频片段并添加音频轨道
     * 
     * @param segmentPaths 视频片段路径列表
     * @param outputVideoPath 输出视频路径
     * @param audioPath 音频文件路径
     * @param progressCallback 进度回调
     * @return 合并成功返回true，失败返回false
     */
    public static boolean mergeVideoSegmentsWithAudio(List<String> segmentPaths, String outputVideoPath, 
                                                     String audioPath, ProgressCallback progressCallback) {
        // 检查输入参数
        if (segmentPaths == null || segmentPaths.isEmpty()) {
            LogUtil.error("SegmentedVideoProcessor", "mergeVideoSegmentsWithAudio", "视频片段路径列表为空");
            return false;
        }
        
        return mergeVideoSegmentsWithAudioInternal(segmentPaths, outputVideoPath, audioPath, progressCallback);
    }
    
    /**
     * 合并视频片段并添加音频轨道的内部实现
     * 
     * @param segmentPaths 视频片段路径列表
     * @param outputVideoPath 输出视频路径
     * @param audioPath 音频文件路径
     * @param progressCallback 进度回调
     * @return 合并成功返回true，失败返回false
     */
    private static boolean mergeVideoSegmentsWithAudioInternal(List<String> segmentPaths, String outputVideoPath, 
                                                              String audioPath, ProgressCallback progressCallback) {
        FFmpegFrameGrabber firstGrabber = null;
        FFmpegFrameRecorder recorder = null;
        
        try {
            LogUtil.debug("SegmentedVideoProcessor", "mergeVideoSegmentsWithAudioInternal", "开始合并视频片段并添加音频轨道");
            LogUtil.debug("SegmentedVideoProcessor", "mergeVideoSegmentsWithAudioInternal", "视频片段数量: " + segmentPaths.size());
            LogUtil.debug("SegmentedVideoProcessor", "mergeVideoSegmentsWithAudioInternal", "输出路径: " + outputVideoPath);
            
            // 先从第一个片段获取视频参数
            firstGrabber = new FFmpegFrameGrabber(segmentPaths.get(0));
            firstGrabber.start();
            int imageWidth = firstGrabber.getImageWidth();
            int imageHeight = firstGrabber.getImageHeight();
            double frameRate = firstGrabber.getFrameRate();
            firstGrabber.stop();
            firstGrabber.release();
            firstGrabber = null;
            
            LogUtil.debug("SegmentedVideoProcessor", "mergeVideoSegmentsWithAudioInternal", "视频参数 - 宽度: " + imageWidth + ", 高度: " + imageHeight + ", 帧率: " + frameRate);
            
            // 创建视频录制器
            recorder = new FFmpegFrameRecorder(outputVideoPath, imageWidth, imageHeight);
            recorder.setVideoCodec(org.bytedeco.ffmpeg.global.avcodec.AV_CODEC_ID_H264);
            recorder.setFormat("mp4");
            recorder.setFrameRate(frameRate);
            recorder.setPixelFormat(org.bytedeco.ffmpeg.global.avutil.AV_PIX_FMT_YUV420P);
            recorder.setVideoBitrate(2000000);
            
            // 如果有音频路径，设置音频参数
            if (audioPath != null && !audioPath.isEmpty()) {
                LogUtil.debug("SegmentedVideoProcessor", "mergeVideoSegmentsWithAudioInternal", "设置音频参数，音频路径: " + audioPath);
                try {
                    FFmpegFrameGrabber audioGrabber = new FFmpegFrameGrabber(audioPath);
                    audioGrabber.start();
                    // 使用AAC编解码器而不是直接复制源音频的编解码器
                    recorder.setAudioCodec(org.bytedeco.ffmpeg.global.avcodec.AV_CODEC_ID_AAC);
                    recorder.setSampleRate(audioGrabber.getSampleRate());
                    recorder.setAudioChannels(audioGrabber.getAudioChannels());
                    recorder.setAudioBitrate(192000); // 设置固定的音频比特率192kbps
                    audioGrabber.stop();
                    audioGrabber.release();
                } catch (Exception e) {
                    LogUtil.error("SegmentedVideoProcessor", "mergeVideoSegmentsWithAudioInternal", "设置音频参数失败: " + e.getMessage());
                }
            }
            
            recorder.start();
            LogUtil.debug("SegmentedVideoProcessor", "mergeVideoSegmentsWithAudioInternal", "录制器已启动");
            
            // 合并视频片段
            LogUtil.debug("SegmentedVideoProcessor", "mergeVideoSegmentsWithAudioInternal", "开始合并视频片段");
            long totalVideoFrames = 0; // 记录总视频帧数
            for (int i = 0; i < segmentPaths.size(); i++) {
                String segmentPath = segmentPaths.get(i);
                LogUtil.debug("SegmentedVideoProcessor", "mergeVideoSegmentsWithAudioInternal", "处理片段 " + i + ": " + segmentPath);
                
                FFmpegFrameGrabber grabber = null;
                try {
                    grabber = new FFmpegFrameGrabber(segmentPath);
                    grabber.start();
                    
                    Frame frame;
                    int frameCount = 0;
                    while ((frame = grabber.grabFrame()) != null) {
                        recorder.record(frame);
                        frameCount++;
                        totalVideoFrames++;
                    }
                    
                    LogUtil.debug("SegmentedVideoProcessor", "mergeVideoSegmentsWithAudioInternal", "片段 " + i + " 处理完成，帧数: " + frameCount);
                } catch (Exception e) {
                    LogUtil.error("SegmentedVideoProcessor", "mergeVideoSegmentsWithAudioInternal", "处理片段 " + i + " 时出错: " + e.getMessage());
                    throw e;
                } finally {
                    if (grabber != null) {
                        try {
                            grabber.stop();
                            grabber.release();
                        } catch (Exception e) {
                            LogUtil.error("SegmentedVideoProcessor", "mergeVideoSegmentsWithAudioInternal", "关闭片段 " + i + " 的grabber时出错: " + e.getMessage());
                        }
                    }
                }
                
                // 更新进度（视频合并占总进度的50%）
                if (progressCallback != null) {
                    int progress = (int) ((i + 1) * 50.0 / segmentPaths.size());
                    progressCallback.onProgress("合并视频片段 " + (i + 1) + "/" + segmentPaths.size(), progress);
                }
            }
            
            LogUtil.debug("SegmentedVideoProcessor", "mergeVideoSegmentsWithAudioInternal", "所有视频片段合并完成，总帧数: " + totalVideoFrames);
            
            // 复制音频轨道
            if (audioPath != null && !audioPath.isEmpty()) {
                LogUtil.debug("SegmentedVideoProcessor", "mergeVideoSegmentsWithAudioInternal", "开始复制音频轨道");
                if (progressCallback != null) {
                    progressCallback.onProgress("正在复制音频轨道...", 55);
                }
                copyAudioTrackSimple(audioPath, recorder, progressCallback);
            }
            
            // 关闭录制器
            LogUtil.debug("SegmentedVideoProcessor", "mergeVideoSegmentsWithAudioInternal", "开始停止录制器");
            recorder.stop();
            recorder.release();
            recorder = null;
            LogUtil.debug("SegmentedVideoProcessor", "mergeVideoSegmentsWithAudioInternal", "录制器已停止并释放");
            
            LogUtil.debug("SegmentedVideoProcessor", "mergeVideoSegmentsWithAudioInternal", "视频片段合并完成");
            return true;
        } catch (Exception e) {
            LogUtil.error("SegmentedVideoProcessor", "mergeVideoSegmentsWithAudioInternal", "合并视频片段失败: " + e.getMessage());
            e.printStackTrace();
            
            // 确保资源被正确释放
            try {
                if (firstGrabber != null) {
                    firstGrabber.stop();
                    firstGrabber.release();
                }
            } catch (Exception ex) {
                LogUtil.error("SegmentedVideoProcessor", "mergeVideoSegmentsWithAudioInternal", "关闭firstGrabber时出错: " + ex.getMessage());
            }
            
            try {
                if (recorder != null) {
                    recorder.stop();
                    recorder.release();
                }
            } catch (Exception ex) {
                LogUtil.error("SegmentedVideoProcessor", "mergeVideoSegmentsWithAudioInternal", "关闭recorder时出错: " + ex.getMessage());
            }
            
            return false;
        } finally {
            // 强制进行垃圾回收
            System.gc();
        }
    }
    
    /**
     * 简化的音频复制方法
     * 参考SpectrumVideoGenerator中的copyAudioTrackSimple方法实现
     */
    private static void copyAudioTrackSimple(String audioPath, FFmpegFrameRecorder recorder, ProgressCallback progressCallback) {
        FFmpegFrameGrabber audioGrabber = null;
        try {
            LogUtil.debug("SegmentedVideoProcessor", "copyAudioTrackSimple", "开始复制音频轨道，音频路径: " + audioPath);
            audioGrabber = new FFmpegFrameGrabber(audioPath);
            audioGrabber.start();

            Frame audioFrame;
            int count = 0;
            while ((audioFrame = audioGrabber.grabFrame()) != null) {
                if (audioFrame.samples != null) {
                    try {
                        recorder.record(audioFrame);
                        count++;
                    } catch (Exception e) {
                        LogUtil.error("SegmentedVideoProcessor", "copyAudioTrackSimple", "记录音频帧时出错: " + e.getMessage());
                        // 继续处理其他音频帧，不中断整个过程
                    }

                    // 更新进度（音频复制占总进度的40%）
                    if (progressCallback != null && count % 100 == 0) { // 每100帧更新一次进度
                        // 音频复制进度从55%开始，到95%结束
                        int progress = 55 + (int) ((double) count / (count + 1000) * 40); // 简化的进度计算
                        if (progress > 95) progress = 95;
                        progressCallback.onProgress("正在复制音频轨道... " + (count+1) + "帧", progress);
                    }
                }
                // 立即释放音频帧资源
                if (audioFrame != null) {
                    try {
                        audioFrame.close();
                    } catch (Exception e) {
                        LogUtil.error("SegmentedVideoProcessor", "copyAudioTrackSimple", "关闭音频帧时出错: " + e.getMessage());
                    }
                    audioFrame = null;
                }
            }
            LogUtil.debug("SegmentedVideoProcessor", "copyAudioTrackSimple", "音频处理完成，共处理 " + count + " 帧");
        } catch (Exception e) {
            LogUtil.error("SegmentedVideoProcessor", "copyAudioTrackSimple", "复制音频轨道失败: " + e.getMessage());
            e.printStackTrace();
        } finally {
            if (audioGrabber != null) {
                try {
                    audioGrabber.stop();
                    audioGrabber.release();
                    LogUtil.debug("SegmentedVideoProcessor", "copyAudioTrackSimple", "音频抓取器已释放");
                } catch (Exception e) {
                    LogUtil.error("SegmentedVideoProcessor", "copyAudioTrackSimple", "释放音频抓取器失败: " + e.getMessage());
                }
            }
        }
    }
}